<template>
  <div class="assign-role" v-loading="loading">
    <el-drawer title="分配角色" v-model="drawerVisible" size="30%">
      <template #default>
        <el-tree ref="treeRef" :data="menuArr" :props="props" node-key="id" :default-checked-keys="selectArr" show-checkbox @node-click="" default-expand-all />
      </template>

      <template #footer>
        <span>
          <el-button @click="cancel">取消</el-button>
          <el-button type="primary" @click="save">确定</el-button>
        </span>
      </template>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue'
  import type { RoleData, MenuResponseData, MenuList } from '@/api/acl/role/type'
  import { reqAllMenuList, reqSetPermisstion } from '@/api/acl/role'
  import { getElMessage } from '@/utils/message'
  import { ElTree } from 'element-plus'

  const $emits = defineEmits(['reload'])

  const drawerVisible = ref<boolean>(false)
  const menuArr = ref<MenuList>([])
  const selectArr = ref<number[]>([])
  const loading = ref<boolean>(false)
  const treeRef = ref<InstanceType<typeof ElTree>>()
  const roleId = ref<number>(0)
  const props = {
    label: 'name',
    children: 'children',
  }
  function open(role: RoleData) {
    drawerVisible.value = true
    roleId.value = role.id as number
    getAllMenuList(role)
  }

  async function save() {
    const selectId = treeRef.value?.getCheckedKeys() as number[]
    const selectHalfId = treeRef.value?.getHalfCheckedKeys() as number[]
    const permissionId = [...selectId, ...selectHalfId]

    try {
      const res: any = await reqSetPermisstion(roleId.value, permissionId)
      if (res.code === 200) {
        getElMessage('设置成功', 'success')
      } else {
        getElMessage('设置失败', 'success')
      }
    } catch (error) {
      getElMessage((error as Error).message, 'error')
    } finally {
      drawerVisible.value = false
      $emits('reload')
    }
  }

  async function getAllMenuList(role: RoleData) {
    try {
      role.assignLoading = true
      const res: MenuResponseData = await reqAllMenuList(role.id as number)
      if (res.code === 200) {
        menuArr.value = res.data
        selectArr.value = filterSelectArr(menuArr.value, [])
      } else {
        getElMessage('获取角色角色列表失败', 'error')
      }
    } catch (error) {
      getElMessage((error as Error).message, 'error')
    } finally {
      role.assignLoading = false
    }
  }

  function filterSelectArr(allData: MenuList, initArr: number[]) {
    // 不能直接将一级的select为true的id追加到initArr中，如果追加的话，会导致全部树形控件全部勾选，解决方法应该为只追加最后一级select为true的id
    allData.forEach((item) => {
      if (item.select && item.level === 4) {
        initArr.push(item.id)
      }

      if (item.children && item.children.length > 0) {
        filterSelectArr(item.children, initArr)
      }
    })
    return initArr
  }

  function cancel() {
    drawerVisible.value = false
  }
  defineExpose({
    open,
  })
</script>

<style lang="scss" scoped></style>
